package com.rawchen.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rawchen.entity.Blog;
import com.rawchen.model.dto.BlogView;
import com.rawchen.model.dto.BlogVisibility;
import com.rawchen.model.vo.*;
import org.apache.ibatis.annotations.Mapper;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @Description: 博客文章持久层接口
 */
@Mapper
@Repository
public interface BlogMapper extends BaseMapper<Blog> {
	/**
	 * 按标题和分类查询博客List
	 *
	 * @param title      标题
	 * @param categoryId 分类ID
	 * @return 博客list
	 */
	List<Blog> getListByTitleAndCategoryId(@Nullable String title, @Nullable Integer categoryId);

	/**
	 * 按关键字根据文章内容搜索公开且无密码保护的博客文章。搜索范围包括标题、内容、描述
	 *
	 * @param query 内容关键词
	 * @return 搜索到的博客list
	 */
	List<SearchBlog> getSearchBlogListByQueryAndIsPublished(String query);

	/**
	 * 查询所有博客id和title，并按照创建时间倒叙的顺序排序
	 *
	 * @return 查询结果
	 */
	List<BlogIdAndTitle> getIdAndTitleList();

	/**
	 * 查询最新公开博客，并按照创建时间倒叙的顺序排序
	 *
	 * @return 查询结果
	 */
	List<NewBlog> getNewBlogListByIsPublished();

	/**
	 * 查询公开博客的简要信息
	 *
	 * @return 查询结果
	 */
	List<BlogInfo> getBlogInfoListByIsPublished();

	/**
	 * 根据分类name查询公开博客List
	 *
	 * @param categoryName 分类名
	 * @return 查询结果
	 */
	List<BlogInfo> getBlogInfoListByCategoryNameAndIsPublished(String categoryName);

	/**
	 * 根据标签name查询公开博客List
	 *
	 * @param tagName 标签名
	 * @return 查询结果
	 */
	List<BlogInfo> getBlogInfoListByTagNameAndIsPublished(String tagName);

	/**
	 * 查询公开博客年月List，并按倒叙排序
	 *
	 * @return 公开博客的创建时间，格式为 %Y年%m月
	 */
	List<String> getGroupYearMonthByIsPublished();

	/**
	 * 按年月查询公开博客简要信息List
	 *
	 * @param yearMonth 博客创建时间，格式为 %Y年%m月
	 * @return 查询结果
	 */
	List<ArchiveBlog> getArchiveBlogListByYearMonthAndIsPublished(String yearMonth);

	/**
	 * 查询随机的公开且推荐文章，内部使用 order by rand() 实现，博客数量较大时可能会有效率问题
	 *
	 * @param limitNum 查询的博客数量
	 * @return 查询结果
	 */
	List<RandomBlog> getRandomBlogListByLimitNumAndIsPublishedAndIsRecommend(Integer limitNum);

	/**
	 * 查询所有文章的浏览量
	 */
	List<BlogView> getBlogViewsList();

	/**
	 * 维护 blog_tag 表(删除)
	 *
	 * @param blogId 要删除映射关系的博客ID
	 */
	int deleteBlogTagByBlogId(Long blogId);

	/**
	 * 维护 blog_tag 表(添加)
	 *
	 * @param blogId 博客ID
	 * @param tagId  标签ID
	 */
	int saveBlogTag(Long blogId, Long tagId);

	/**
	 * 添加博客
	 *
	 * @param blog 需要添加的博客数据
	 */
	int saveBlog(com.rawchen.model.dto.Blog blog);

	/**
	 * 更新博客推荐状态
	 *
	 * @param blogId    博客ID
	 * @param recommend 是否推荐
	 */
	int updateBlogRecommendById(Long blogId, Boolean recommend);

	/**
	 * 更新博客可见性状态
	 *
	 * @param blogId 博客ID
	 * @param bv     博客相关的可见性数据
	 */
	int updateBlogVisibilityById(Long blogId, BlogVisibility bv);

	/**
	 * 更新博客置顶状态
	 *
	 * @param blogId 博客ID
	 * @param top    是否置顶
	 */
	int updateBlogTopById(Long blogId, Boolean top);

	/**
	 * 更新博客阅读次数
	 *
	 * @param blogId
	 * @param views  阅读次数
	 */
	int updateViews(Long blogId, Integer views);

	/**
	 * 按id查询博客
	 *
	 * @param id 博客ID
	 */
	Blog getBlogById(Long id);

	/**
	 * 按id查询博客标题
	 *
	 * @param id 博客ID
	 */
	String getTitleByBlogId(Long id);

	/**
	 * 按id查询公开博客
	 *
	 * @param id 博客ID
	 */
	BlogDetail getBlogByIdAndIsPublished(Long id);

	/**
	 * 查询受密码保护文章密码
	 *
	 * @param blogId 博客ID
	 */
	String getBlogPassword(Long blogId);

	/**
	 * 更新博客
	 *
	 * @param blog 新的博客数据
	 */
	int updateBlogById(com.rawchen.model.dto.Blog blog);

	/**
	 * 查询公开博客总数
	 */
	int countBlogByIsPublished();

	/**
	 * 按分类id查询博客数量
	 *
	 * @param categoryId 分类ID
	 */
	int countBlogByCategoryId(Long categoryId);

	/**
	 * 按标签id查询博客数量（不包含逻辑删除的博客数据）
	 *
	 * @param tagId 标签ID
	 */
	int countBlogByTagId(Long tagId);

	/**
	 * 查询博客是否启用评论
	 *
	 * @param blogId 博客ID
	 */
	Boolean getCommentEnabledByBlogId(Long blogId);

	/**
	 * 查询博客是否公开
	 *
	 * @param blogId 博客ID
	 */
	Boolean getPublishedByBlogId(Long blogId);

	/**
	 * 查询每个分类的博客数量
	 */
	List<CategoryBlogCount> getCategoryBlogCountList();
}
